<?php
//рус
include_once(_APP_PATH. "business/groups/groups_mapper.php");
class active_user_class
{
    /**
		залогинен ли юзер
     */
    private $_isLogged = false;
    /**
		id юзера в системе
     */
    private $_id = false;
    /**
		id основной группы
     */
    private $_groupId = 0;
    /**
		логин юзера
     */
    private $_userName;
    /**
		массив дополнительных групп
     */
    private $_grantedGroups = array();
    /**
		массив из доп.групп и основной группы
     */
    private $_allGroups = array();
    /**
		доступ по всем контроллерам
     */
    private $_access = false;

    protected $_libs;
    protected $_isError = false;
    protected $_errorMessage;
    
    protected $_availableGroups = false;
    
    private $_groupsMapper;
    /**
		второстепенные данные пользователя
     */
    private $_details = array();
    public function __construct ()
    {
        $this->_libs = SysLoader::GetLibCollection();
    }
    
    private function GetGroupsMapper()
    {
		if (!$this->_groupsMapper) 
		{
			$this->_groupsMapper = GroupsMapper::GetInstance($this); 
		}
		return $this->_groupsMapper;     	
    }      
    
    public function Set ($isLogged, $id, $username, $groupId, $grantedGroups)
    {
        $this->SetStatus($isLogged)
        	 ->SetId($id)
        	 ->SetUserName($username)
        	 ->SetGroups($groupId, $grantedGroups);
        	 
        return $this;
    }
    public function Reset ()
    {
        $this->SetStatus(false)
        	 ->SetId(0)
        	 ->SetUserName(null)
        	 ->SetGroups(0, array())
        	 ->ResetDetails();
        	 
        return $this;
    }
    
    public function IsSuperUser()
    {
    	return $this->GetGroupId() == MozgCfg::GetProp('global/users//superUser/groupId');
    }
    /**
		возвращает true, если юзер залогинен в системе
     */
    public function IsLogged ()
    {
        return $this->_isLogged;
    }
    /**
		устанавливает статус юзера в системе
     */
    public function SetStatus ($isLogged = false)
    {
        $this->_isLogged = (bool) $isLogged;
        return $this;
    }
    /**
		возвращает id юзера
     */
    public function GetId ()
    {
        return $this->_id;
    }
    /**
		устанавливает id юзера
     */
    public function SetId($id)
    {
        $this->_id = (int)$id;
        return $this;
    }
    /**
		возвращает username юзера
     */
    public function GetUserName ()
    {
        return $this->_userName;
    }
    /**
		устанавливает username юзера
     */
    public function SetUserName ($username)
    {
        $this->_userName = (string) $username;
        return $this;
    }
    /**
		возвращает id основной группы
     */
    public function GetGroupId ()
    {
        return $this->_groupId;
    }
    /**
		устанавливает id основной группы
     */
    public function SetGroupId ($groupId)
    {
    	if ($groupId != $this->_groupId)
    	{
	        $this->_groupId = (int) $groupId;
	        $this->SetGroupsTotal();
    	}    
        return $this;
    }
    /**
		возвращает id основной группы
     */
    public function GetGrantedGroups()
    {
        return $this->_grantedGroups;
    }
    /**
		устанавливает id дополнительных групп
     */
    public function SetGrantedGroups(Array $groups = array())
    {
    	if (sizeof(array_intersect($this->_grantedGroups, $groups)) != sizeof($this->_grantedGroups))
    	{
	    	$this->_grantedGroups = $groups;
	        $this->SetGroupsTotal();
    	}	        
        return $this;
    }
    /**
		устанавливает основную и доп. группы
     */
    public function SetGroups($groupId, Array $groups = array())
    {
        $this->SetGroupId($groupId);
        $this->SetGrantedGroups($groups);
        return $this;
    }
    private function SetGroupsTotal()
    {
        $this->_allGroups = array_merge($this->_grantedGroups, (array) $this->_groupId);
        $this->_allGroups = array_unique($this->_allGroups);
        $this->_availableGroups = false;
        $this->_access = false;
        
        return $this;
    }

    public function GetAllGroups()
    {
        return $this->_allGroups;
    }    
    
    /**
		возвращает список доступных юзеру групп
	*/
    public function GetAvailableGroups()
    {
    	if (false === $this->_availableGroups)
    	{
			$this->_availableGroups = $this->GetGroupsMapper()->GetSubGroupsIds($this->_allGroups, true);    	
    	}
		return $this->_availableGroups;   	
    }    
    
    private function LoadGroupsAccess()
    {
        if (false === $this->_access)
        {
        	$this->_access = $this->GetGroupsMapper()->GetMergedGroupAccessFromCache($this->_allGroups);
        }
    }

    /**
     * 
     * @param $moduleId - id или имя модуля
     * @param $ctrlId - id или имя контроллера
     * @param $actionId - id или имя экшена
     * @return unknown_type
     */
    public function CheckAccess($moduleId, $ctrlId, $actionId)
    {
    	if (!$moduleId || !$ctrlId || !$actionId) return true;
    	
        if (!is_int($moduleId) && !is_int($ctrlId) && !is_int($actionId))
        {
        	$module = SysLoader::GetModuleCollection()->GetModuleDetails($moduleId);
        	$ctrl = SysLoader::GetModuleCollection()->GetCtrlDetails($moduleId, $ctrlId);       	
        	$action = SysLoader::GetModuleCollection()->GetActionDetails($moduleId, $ctrlId, $actionId);
        	
        	$moduleId = $module['id'];
        	$ctrlId = $ctrl['id']; 
        	$actionId = $action['id']; 
        }

        $moduleId = (int)$moduleId;
        $ctrlId = (int)$ctrlId;
        $actionId = (int)$actionId;
        
        if (!$moduleId || !$ctrlId || !$actionId) return true;    	
    	
        if (!$this->IsLogged()) return false;  	    	
        if (MozgCfg::GetProp('global/users//superUser/groupId') == $this->GetGroupId()) return true;
        
        $this->LoadGroupsAccess();        
        if (!isset($this->_access[$moduleId])) return false;
        
        return $this->GetGroupsMapper()->CheckAccess($this->_access[$moduleId], $ctrlId, $actionId);
    }
    
    private $_avatar;
    
    public function SetAvatar($avatar)
    {
		$this->_avatar = $avatar;    	
    }
    
	public function GetAvatar()
	{
		if (!strlen($this->_avatar)) return MozgCfg::GetProp('global/users//noAvatar');
		return $this->_avatar;
	}    
    
    /**
		к второстепенным данным юзера можно обращаться
		как к свойствам этого класса
     */
    private function __get ($property)
    {
        $this->CheckVar($property);
        return $this->_details[$property];
    }
    private function __set ($property, $value)
    {
        $this->CheckVar($property);
        $this->_details[$property] = $value;
    }
    private function __isset ($property)
    {
        $this->CheckVar($property);
        return isset($this->_details[$property]);
    }
    private function __unset ($property)
    {
        $this->CheckVar($property);
        if ($this->__isset($this->_details[$property]))
            unset($this->_details[$property]);
    }
    private function CheckVar ($name)
    {
        if (property_exists(__CLASS__, $name))
            throw new Exception('Доступ к закрытому свойству класса ' . __CLASS__ . ' запрещён');
        return true;
    }
    public function SetDetails (Array $details)
    {
        foreach ($details as $k => $v) {
            $this->__set($k, $v);
        }
        return $this;
    }
    public function GetDetails ()
    {
        return $this->_details;
    }
    public function ResetDetails()
    {
        $this->_details = array();
        return $this;
    }
    /**
		работа в сообщениями об ошибках
     */
    public function SetError ($message)
    {
        $this->_isError = true;
        $this->_errorMessage = $message;
        return $this;
    }
    public function IsError ()
    {
        return $this->_isError;
    }
    public function GetErrorMessage ()
    {
        return $this->_errorMessage;
    }
}